package com.dysm.spring.security.resource.config.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dysm.spring.security.resource.annotion.Anonymous;
import com.dysm.spring.security.resource.config.context.UserContext;
import com.dysm.spring.security.resource.config.context.UserContextUtil;
import com.dysm.spring.security.resource.exception.TokenValidateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

//@Configuration
public class TokenInterceptor extends HandlerInterceptorAdapter implements InitializingBean {

    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    private static final Map<String, UserContext> userMap = new HashMap<>();

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  {
        String requestURI = request.getRequestURI();
        String bodyStr = getInputStreamStr(request);
        LOG.info("call TokenInterceptor.preHandle requestURI:{},body:{}", requestURI, bodyStr);
        LOG.info("==================" + this.getClass());
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Anonymous anonymous = handlerMethod.getMethodAnnotation(Anonymous.class);
        if (anonymous != null) {
            return Boolean.TRUE;
        }
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            throw new TokenValidateException("token is empty!");
        }
        String userName;
        try {
            Map<String, String> varMap = new HashMap<>();
            varMap.put("token", token);
            String returnJson = restTemplate.postForObject("http://localhost:8080/oauth/check_token?token=" + token,
                    null, String.class, varMap);
            LOG.info("returnJson:" + returnJson);
            JSONObject jsonObject = JSON.parseObject(returnJson);
            userName = (String) jsonObject.get("user_name");
        } catch (Exception e) {
            LOG.error("token校验请求异常,token:{}", token, e);
            throw new TokenValidateException("token is invalid!");
        }

        if (StringUtils.isEmpty(userName)) {
            throw new TokenValidateException("user is not exist!");
        }

        UserContext userContext = userMap.get(userName);
        if (userContext == null) {
            throw new TokenValidateException("user [" + userName +"] is not exist!");
        }
        UserContextUtil.set(userContext);
        return true;
    }

    @Override
    public void afterPropertiesSet() {
        userMap.put("xiay", new UserContext("xiay", "13234567890", "10001"));
        userMap.put("lis", new UserContext("lis", "15234567890", "10002"));
        userMap.put("zhangs", new UserContext("zhangs", "18234567890", "10003"));
    }

    private String getInputStreamStr(HttpServletRequest request) {
        try {
            return StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset());
        } catch (IOException e) {
            LOG.error("读取inputStream异常：", e);
        }
        return null;
    }
}
